package com.xyh.backend3.tool;

import com.xyh.backend3.pojo.ColumnDiff;
import com.xyh.backend3.pojo.CompareResult;
import com.xyh.backend3.pojo.Db;
import com.xyh.backend3.pojo.TableDiff;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class DbComparator {
    // 定义常量
    private static final int TABLE_MISSING_IN_DB2 = 1;// 表在 db1 中存在，在 db2 中不存在
    private static final int TABLE_MISSING_IN_DB1 = 2;// 表在 db2 中存在，在 db1 中不存在
    private static final int COLUMN_MISSING_IN_DB2 = 3;// 列在 db1 中存在，在 db2 中不存在
    private static final int COLUMN_MISSING_IN_DB1 = 4;// 列在 db2 中存在，在 db1 中不存在

    // 比较两个数据库
    public CompareResult compare(Db db1, Db db2) {
        // 定义结果
        ArrayList<TableDiff> tableDiffs = new ArrayList<>();
        ArrayList<ColumnDiff> columnDiffs = new ArrayList<>();

        db1.setUrl("jdbc:mysql://localhost:3306/db1");
        db1.setUsername("root");
        db1.setPassword("111111");

        db2.setUrl("jdbc:mysql://localhost:3306/db2");
        db2.setUsername("root");
        db2.setPassword("111111");

        // 获取连接
        try (Connection conn1 = getConnection(db1);
             Connection conn2 = getConnection(db2)) {

            // 获取元数据
            DatabaseMetaData meta1 = conn1.getMetaData();
            DatabaseMetaData meta2 = conn2.getMetaData();

            // 获取 db1 和 db2 中的表
            ResultSet tables1 = meta1.getTables(null, null, "%", null);
            ResultSet tables2 = meta2.getTables(null, null, "%", null);

            // 获取 db1 中的表
            Set<String> tablesInDb1 = new HashSet<>();
            while (tables1.next()) {
                String tableName = tables1.getString("TABLE_NAME");
                tablesInDb1.add(tableName);
            }

            // 获取 db2 中的表
            Set<String> tablesInDb2 = new HashSet<>();
            while (tables2.next()) {
                String tableName = tables2.getString("TABLE_NAME");
                tablesInDb2.add(tableName);
            }

            // 比较表
            tableDiffs.addAll(tablesInDb1.stream()
                    .filter(table -> !tablesInDb2.contains(table))// db1 中存在，db2 中不存在
                    .map(table -> new TableDiff(table, TABLE_MISSING_IN_DB2))// 创建 TableDiff 对象
                    .collect(Collectors.toList()));// 转换为 List

            tableDiffs.addAll(tablesInDb2.stream()
                    .filter(table -> !tablesInDb1.contains(table))// db2 中存在，db1 中不存在
                    .map(table -> new TableDiff(table, TABLE_MISSING_IN_DB1))// 创建 TableDiff 对象
                    .collect(Collectors.toList()));// 转换为 List

            // 对于每个共同的表，比较列
            List<String> commonTables = new ArrayList<>(tablesInDb1);
            commonTables.retainAll(tablesInDb2);

            for (String table : commonTables) {
                ResultSet columns1 = meta1.getColumns(null, null, table, null);
                ResultSet columns2 = meta2.getColumns(null, null, table, null);

                // 比较列
                Set<String> columnsInDb1 = new HashSet<>();
                while (columns1.next()) {
                    columnsInDb1.add(columns1.getString("COLUMN_NAME"));// 获取列名
                }

                Set<String> columnsInDb2 = new HashSet<>();
                while (columns2.next()) {
                    columnsInDb2.add(columns2.getString("COLUMN_NAME"));// 获取列名
                }

                columnDiffs.addAll(columnsInDb1.stream()
                        .filter(column -> !columnsInDb2.contains(column))// db1 中存在，db2 中不存在
                        .map(column -> new ColumnDiff(table, column, COLUMN_MISSING_IN_DB2))// 创建 ColumnDiff 对象
                        .collect(Collectors.toList()));// 转换为 List

                columnDiffs.addAll(columnsInDb2.stream()
                        .filter(column -> !columnsInDb1.contains(column))// db2 中存在，db1 中不存在
                        .map(column -> new ColumnDiff(table, column, COLUMN_MISSING_IN_DB1))// 创建 ColumnDiff 对象
                        .collect(Collectors.toList()));// 转换为 List
            }
        } catch (Exception e) {
            // 更好的异常处理
            // 这里可以记录异常日志
            System.err.println("数据库比较时发生错误: " + e.getMessage());
            e.printStackTrace();
        }

        return new CompareResult(tableDiffs, columnDiffs);
    }

    // 获取连接
    private Connection getConnection(Db db) throws Exception {
        if (db == null || db.getUrl() == null || db.getUrl().isEmpty()) {// 检查 db 对象和 url 是否为空
            throw new IllegalArgumentException("数据库URL没有创建");
        }
        return DriverManager.getConnection(db.getUrl(), db.getUsername(), db.getPassword());
    }
}
